package com.zonda.study.opengl.image;

import android.content.Context;
import android.opengl.GLES20;

/**
 * Created by zhuqiuzhu on 17/3/24.
 * 着色器程序
 */

public class ShaderProgram {

    /*--着色器 Uniform 常量--*/
    //顶点着色器中，用于定位 OpenGL 的一个 4x4 的浮点矩阵
    static final String U_MATRIX = "u_Matrix";
    //片元着色器中，用于接收纹理的 2D 纹理对象
    static final String U_TEXTURE_UNIT = "u_TextureUnit";

    /*--着色器 Attribute 常量--*/
    //顶点着色器中，用于定位的 4 维浮点数向量
    static final String A_POSITION = "a_Position";
    //顶点着色器中，用于定位纹理的 2 维浮点数向量
    static final String A_TEXTURE_COORDINATES = "a_TextureCoordinates";

    private final int uMatrixLocation;
    private final int uTextureUnitLocation;

    private final int aPositionLocation;
    private final int aTextureCoordinatesLocation;

    private final int mProgram;

    protected ShaderProgram(Context context, int vertexShaderResourceId,
                            int fragmentShaderResourceId) {
        final String vertexShaderStatement = TextResourceReader
                .readTextFileFromResource(context, vertexShaderResourceId);
        final String fragmentShaderStatement = TextResourceReader
                .readTextFileFromResource(context, fragmentShaderResourceId);
        mProgram = ShaderHelper.buildProgram(vertexShaderStatement, fragmentShaderStatement);

        uMatrixLocation = GLES20.glGetUniformLocation(mProgram, U_MATRIX);
        uTextureUnitLocation = GLES20.glGetUniformLocation(mProgram, U_TEXTURE_UNIT);

        aPositionLocation = GLES20.glGetAttribLocation(mProgram, A_POSITION);
        aTextureCoordinatesLocation = GLES20.glGetAttribLocation(mProgram, A_TEXTURE_COORDINATES);
    }

    /**
     * 设置 Uniform
     *
     * @param matrix    投射矩阵
     * @param textureId 纹理 ID
     */
    public void setUniform(float[] matrix, int textureId) {

        //将投射矩阵加入到着色器程序中
        GLES20.glUniformMatrix4fv(uMatrixLocation, 1, false, matrix, 0);

        //把活动的纹理单元设置为纹理单元 0
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);

        //把纹理绑定到这个单元
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);

        //把被选定的纹理单元传递给片段着色器中 u_TextureUnit
        GLES20.glUniform1i(uTextureUnitLocation, 0);
    }

    public void useProgram() {
        GLES20.glUseProgram(mProgram);
    }

    public int getPositionAttributeLocation() {
        return aPositionLocation;
    }

    public int getTextureCoordinatesAttributeLocation() {
        return aTextureCoordinatesLocation;
    }
}
